/*************************************************
* Title：TinyToolKit
* Author：Opportunity 
* Describe：AB版本比较
* CreateTime：2020-07-14 10:44:03
* Version：1.0
* Modify Recorder：
*************************************************/

using System;
using System.Collections.Generic;
using System.IO;
using UnityEngine;

namespace TinyToolKit.AssetLoad
{
    public class ABVersionHelper
    {
        private Dictionary<string, string> _localResVersion;
        private Dictionary<string, string> _serverResVersion;
        private List<string> _needDownFiles;

        public void UpdateABVersion(string localVersionPath,string serverVersionUrl,DataFormat dataFormat,string abUriPrefix,Action<List<string>> callBack)
        {
            _localResVersion = new Dictionary<string, string>();
            _serverResVersion = new Dictionary<string, string>();
            _needDownFiles = new List<string>();

            TinyUtility.File.LoadTextFileAsync(serverVersionUrl, serverVersionMsg =>
            {
                _serverResVersion = ParseVersionFile(serverVersionMsg,dataFormat);
                
                if (File.Exists(localVersionPath))
                {
                    string localVersionMsg = TinyUtility.File.LoadTextFile(localVersionPath);
                    _localResVersion = ParseVersionFile(localVersionMsg,dataFormat);
                    
                    CompareVersion();
                }
                else
                {
                    foreach (var item in _serverResVersion)
                    {
                        _needDownFiles.Add(item.Key);
                    }
                }
                
                //添加本地未完成下载的AB包名
                foreach (var item in _serverResVersion)
                {
                    string fullPath = Path.Combine(abUriPrefix, item.Key);
                    if(File.Exists(fullPath) == false && _needDownFiles.Contains(item.Key) == false)
                        _needDownFiles.Add(item.Key);
                }
                
                UpdateLocalVersion(localVersionPath,serverVersionMsg);
                callBack.Invoke(_needDownFiles);
            });
        }

        private Dictionary<string,string> ParseVersionFile(string content,DataFormat dataFormat)
        {
            if (content.IsNullOrEmpty())
            {
                TLogTool.Error("内容不能为空");
                return null;
            }
            
            ABVersion abVersion = null;
            switch (dataFormat)
            {
                case DataFormat.Json:
                    abVersion = TinyUtility.Json.ToObject<ABVersion>(content);
                    break;
                case DataFormat.Encrypt:
                    EncryptDecryptBase encryptDecrypt = new EncryptDecrypt_Caesar();
                    content = encryptDecrypt.Decrypt(content);
                    abVersion = TinyUtility.Json.ToObject<ABVersion>(content); 
                    break;
            }
            
            Dictionary<string,string> dic = new Dictionary<string, string>();
            foreach (var item in abVersion.abVersionItems)
            {
                dic.Add(item.abName,item.md5);
            }

            return dic;
        }

        private void CompareVersion()
        {
            foreach (var item in _serverResVersion)
            {
                string abName = item.Key;
                string md5 = item.Value;

                if (_localResVersion.ContainsKey(abName) == false)
                {
                    _needDownFiles.Add(abName);
                }
                else
                {
                    _localResVersion.TryGetValue(abName, out var localMd5);
                    if(md5.Equals(localMd5) == false)
                        _needDownFiles.Add(abName);
                }
            }
        }

        private void UpdateLocalVersion(string filePath ,string contents)
        {
            if (_needDownFiles.Count > 0)
            {
                TinyUtility.File.SaveTextFile(filePath,contents);
            } 
        }
    }

    [Serializable]
    public class ABVersion
    {
        [SerializeField] 
        public List<ABVersionItem> abVersionItems = new List<ABVersionItem>();
    }
    
    [Serializable]
    public class ABVersionItem
    {
        public string abName;
        public string md5;

        public ABVersionItem()
        {
        }

        public ABVersionItem(string abName,string md5)
        {
            this.abName = abName;
            this.md5 = md5;
        }
    }
}
